// polyfill区域
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll
if (!String.prototype.replaceAll) {
  String.prototype.replaceAll = function (str, newStr){

    // If a regex pattern
    if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') {
      return this.replace(str, newStr);
    }

    // If a string
    return this.replace(new RegExp(str, 'g'), newStr);

  };
}

import {initDevApp} from "@/devApp/main";

const getGlobal = function() {
  if (typeof self !== 'undefined') { return self; }
  if (typeof window !== 'undefined') { return window; }
  if (typeof global !== 'undefined') { return global; }
  throw new Error('unable to locate global object');
};

const _global = getGlobal();
_global.global = _global;

/**
 * 初始化CodeMirror
 * @returns {Promise<unknown>}
 */
_global.initCodeMirror = function () {
  return new Promise(resolve => {
    if (!window.CodeMirrorLoaded ) {
      import('@/plugins/CodeMirrorEditor/CodeMirror.vue').then((res) => {
        CustomVueComponent.register(res.default, 'CodeMirror');
        resolve();
      });
    } else {
      resolve()
    }
  })
}
import * as ZY from '@/lib/main.js';
// eslint-disable-next-line no-undef
globalThis.ZY = ZY;
import {extZY} from "@/hooks/zy";
extZY(ZY)

import * as ZY_EXT from '@/lib/ext.js';
// eslint-disable-next-line no-undef
globalThis.ZY_EXT = ZY_EXT;

function buildCustomVueCom() {
  return class CustomVueComponent {
    static defMap = new Map()
    static components = {}
    static app = null
    static component(name, ctx) {
      this.app.component(name, ctx)
      this.defMap.set(name, ctx)
      this.components[name] = ctx
    }
    static register(ctx, name = ctx.name) {
      this.component(name, ctx)
    }
    static registerOnce(ctx, name = ctx.name) {
      if (!this.components[name]) {
        this.component(name, ctx)
      }
    }
    static resolve(str) {
      let components = getAppContext().components
      let comName = ZY.lodash.upperFirst(ZY.lodash.camelCase(str))
      if (components[comName]) {
        return components[comName]
      }
      return str
    }
  }
}
globalThis.CustomVueComponent = buildCustomVueCom()
globalThis.CustomDymComponent = buildCustomVueCom()

import * as Vue from 'vue/dist/vue.cjs'
globalThis.Vue = Vue

globalThis.vueCompositionAPI = Vue;

import * as vuex from 'vuex'
globalThis.Vuex = vuex

import vClickOutside from "click-outside-vue3"

import App from './App.vue'

// element
// import 'element-plus/theme-chalk/src/index.scss';

import 'xy-ui/components/xy-text';
import 'xy-ui/components/xy-tips';
import 'xy-ui/components/xy-tab';
import '@/components/WebElements/index'

class ZShadow extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({mode: 'open'});
  }
  setContent(css, html) {
    // console.log(css, html)

    this.shadowRoot.innerHTML = `<style>:host {display: block; overflow: hidden;} ${css}</style>${html}`
  }
}
window.customElements.define('z-shadow', ZShadow);


import request from '@/requests/index.js'
globalThis.Req = request

import * as Framework from "@/mixins/framework";
globalThis.ZFramework = Framework

import * as ZPageHooks from "@/plugins/z-page/hooks";
globalThis.ZPageHooks = ZPageHooks

import * as ZPageBuild from "@/plugins/z-page/build";
globalThis.ZPageBuild = ZPageBuild

import * as ZFramePlugin from "@/plugins/z-frame/index";

import('./node');

import router, {init_router_start} from './router'
import store from './store'

import icons from './icons/index'
import '@/styles/index.scss' // global css

import * as remote from '@/plugins/remote'
import StoreApp from "./StoreApp.vue";
import DevApp from "./DevApp.vue";

import CustomFormRenderPlugin from "@/plugins/form-render";
import {initStoreApp} from "@/storeApp";

import {initChinaAreaManangerFromUrl} from "@/plugins/chinaArea";

import {initCompile} from "@/hooks/compile";
function comPlugin() {
}
comPlugin.install = function (app) {
  CustomVueComponent.app = app
  CustomDymComponent.app = app
};


import hljs from 'highlight.js'


;(async function () {
  await init_router_start()

  ZY_EXT.marked.setOptions({
    langPrefix:'hljs ',
    highlight: function(code, lang) {
      const language = hljs.getLanguage(lang) ? lang : 'plaintext';
      return hljs.highlight(code, { language }).value
    },
  })

  window.startApp = function () {

    globalThis.renderComForm = initCompile()


    const storeApp = Vue.createApp(StoreApp)
    const app = Vue.createApp(App)
    const devApp = Vue.createApp(DevApp)
    initDevApp(devApp)

    CustomVueComponent.app = app
    CustomDymComponent.app = app

    globalThis.getAppContext = function () {
      return app._context
    }

    app.config.compilerOptions.isCustomElement = tag => {
      return tag === 'app-loading'
    }
    app.config.devtools = true

    storeApp.use({
      install(_a) {
        _a.config.globalProperties.$mainApp = app
      }
    })

    app.config.globalProperties.$zy_deepGet = ZY.deepGet

    // app.use(moduleConfig)
    app.use(remote)
    app.use(globalThis.ElementPlus, {
      size: 'medium',
      // locale
    })
    app.use(comPlugin)
    app.use(vClickOutside)
    app.use(CustomFormRenderPlugin)
    app.use(ZFramePlugin)
    app.use(icons)
    app.use(router)
    app.use(store)
    import('@/plugins/z-frame/formsMana').then(res => {
      // console.log(res)
      app.use(res)
    })
    import('vue3-json-viewer').then(res => {
      // console.log(res.JsonViewer)
      CustomVueComponent.registerOnce( res.JsonViewer, 'v-json-viewer');
    })

    initStoreApp(storeApp)
    app.mount('#app')

    return app
  }

  initChinaAreaManangerFromUrl(
    globalThis.serverRes.area
  ).then((res) => {
    globalThis.chinaAreaManager = res
  })

  if (globalThis.onLibReady) {
    globalThis.onLibReady();
  }
})()
